package com.lsa.skienna.challenge.chap4.the110401_VitosFamily;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.ArrayUtils;

public class Experiments {
	public static void main(String[] args) {
		long min = Long.MAX_VALUE;
		long max = Long.MIN_VALUE;
//		int[] streets = {1, 3, 5, 101, 237, 666, 900};
//		int[] streets = {2, 4,6,8, 10,22,23,66,500, 1000};
		//int[] streets = {2, 4,6,8, 10,22,23,66,500, 1000};
//		int[] streets = {2, 4,6,8, 10,22,23,66,500, 1000};
//		int[] streets = {1,2,3,4,5,6,7,8,9,10};
//		int[] streets = {1,5,10,21};
		int[] streets = {2,4};
		Arrays.sort(streets);
		List<Integer> streetList = Arrays.asList(ArrayUtils.toObject(streets));
		
		Map<Long,Long> num2Freq = new TreeMap<Long, Long>();
		for (int i : streets) {
			Long key = Long.valueOf(i);
			Long freq = num2Freq.get(key);
			if (freq == null) {
				freq = 1L;
			}
			else{
				freq++;
			}
			num2Freq.put(key, freq);
		}
		
		Map<Long, Double> num2Density = num2Density(num2Freq, streets);
		
//		long center = center(streets);
		long minIdx = 0;
		long maxIdx = 0;
		int bnd = streets[streets.length - 1] + 1;
		boolean isShowDistributions = false;
		boolean isShowWeight = true;
		for (int i = 1; i < bnd; ++i) {
			long weigh = weight(i, streets);
			if (isShowDistributions) {
				System.out.print(i + " " + weigh);
			}
			if (num2Freq.containsKey(Long.valueOf(i))) {
				if (isShowDistributions) {
					System.out.println(" density:" + num2Density.get(Long.valueOf(i)));
				}
			}
			else {
				if (isShowDistributions) {
					System.out.println();	
				}
			}
			
			if (isShowWeight && streetList.contains(i)) {
				System.out.println(i + " " + weigh);
			}
			
			if (weigh < min) {
				min = weigh;
				minIdx = i;
			}
			if (weigh > max) {
				max = weigh;
				maxIdx = i;
			}
		}
		
		System.out.println("min:" + minIdx + " " + min);
		System.out.println("max:" + maxIdx + " " + max);
		System.out.println("opt:" + optimal(streets) + " " + weight(optimal(streets), streets) );
	}
	
	private static Map<Long, Double> num2Density(Map<Long,Long> num2Freq, int... streetNums)  {
		Map<Long,Double> num2Density = new TreeMap<Long, Double>();
		for (int i = 1; i < streetNums.length - 1; i++) {
			Long relativesCount = 0L;
			for (int j = i - 1 ; j < i + 2; j++) {
				Long key = Long.valueOf(streetNums[j]);
				relativesCount += num2Freq.get(key);
			}
			double density = relativesCount.doubleValue() / ((double)(streetNums[i + 1] - streetNums[i - 1]));
			Long key = Long.valueOf(streetNums[i]);
			num2Density.put(key, density);
		}
		
		return num2Density;
	}
	
	private static long weight(long vitoAddress, int... streetNums) {
		long total = 0;
		for (int i = 0; i < streetNums.length; i++) {
			total += Math.abs(vitoAddress - streetNums[i]);
		}
		
		return total;
	}
	
	private static long center(int... streetNums) {
		long center = 0;
		
		for (int i = 0; i < streetNums.length; i++) {
			center += streetNums[i];
		}
		
		return (long)(center / streetNums.length);
	}
	
	private static long optimal(int... streetNums) {
		Arrays.sort(streetNums);
		return streetNums.length % 2 == 0? streetNums.length / 2 : streetNums.length / 2 + 1;
	}
}
